#! /usr/bin/env python

#
# Date://02/11/2011 05:40:01 PM (CST) 
# Author: Gou Pengfei
#

import sys
import os
import optparse
import datetime
import re
from subprocess import call
from os.path import join as joinpath

progname = os.path.basename(sys.argv[0])

Usage = '''usage: %prog [options] will generate configuration
files automatically with accordance to the options given by
the user

Enjoy!
'''

optparser = optparse.OptionParser(Usage)

optparser.add_option('-t', '--template', dest='template',
                     default='',
                     help='Name of the template used to generate the'
                     'conf files'
                     " (default: '%default')" )

optparser.add_option('-p', '--parameter', dest='parameter',
                     default='',
                     help='Parameter name which will be set with'
                     'different values'
                     " (default: '%default')")

optparser.add_option('-v', '--values', dest='values',
                     help='Comma separated values of the parameter'
                     " (default:'%default')")

optparser.add_option('-c', '--constant', dest='constant',
                     default = '',
                     help='Two parameters are multiplied, keeping the'
                     'result to constant'
                     " (default:'%default')")

optparser.add_option('-l', '--with_local', dest='with_local',
                     action = 'store_true',
                     default = False,
                     help='Is this a configuration with local history'
                     " (default:'%default')")

optparser.add_option('-n', '--num_tagged_tables',
                     dest='num_tagged_tables',
                     default = '4',
                     help='The number of tagged tables for TAGE'
                     " (default:'%default')")

optparser.add_option('--latex_table', 
                     dest='latex_table_dir',
                     default='',
                     help='The output directory of latex table'
                     " (default:'%defalt')")
                     
(options,leftovers) = optparser.parse_args()

class TAGEParameters(object):
    
    def __init__(self, num_tagged_tables, default_table_size,
            overall_size, **kwargs):

        alpha = float(2)
        l1 = float(20)
        it_num = 0
        found = False
        overall_size = float(overall_size)

        while (it_num < 2**32) :
            histlen = [int(l1*(alpha**i)) for i in range(num_tagged_tables)]

            resources = float(default_table_size * 4)

            for i in range(num_tagged_tables):
                resources += float(2**(histlen[i]) * 16)

            resources = (resources / 8) / 1024

            if resources < 1.1 * overall_size and resources > 0.9 * \
            overall_size:

                self.histlen = histlen
                self.alpha = alpha
                self.l1 = l1

                print "alpha: %f" % alpha
                print "T0 entries: %d" % default_table_size
                for i in range(len(histlen)):
                    print "History length %d: %d" % (i + 1, histlen[i])
                    print "T%d entries: %d" % (i + 1, 2**histlen[i])

                print "TAGE size: %fKB" % resources
                print "------------------"
                print

                self.resources = resources

                found = True
                break

            if l1 > 3:
                l1 -= 1
            elif alpha > 1.0001:
                alpha -= 0.0001
                l1 = 20

            it_num += 1

        if not found:
            print "Cannot find combination for %dKB" % overall_size
            print "------------------"
            print
            sys.exit(1)

class LatexTable(object):
    def __init__(self, **kwargs):
        self.configs = []
        self.params = []
        self.data = [[]]

    def add(self, config, param, data):

        if config not in self.configs:
            self.configs.append(config)
            self.data.append([])

        if param not in self.params:
            self.params.append(param)

        self.data[self.configs.index(config)].append(data)

    def output(self, output_dir):

        output = open(output_dir, 'w')

        # Print table header
        header = 'Configs  & '
        for p in self.params:
            header += p + '  & \t\t'

        header += ' \\\\'

        print >>output, header
        print >>output, '\\hline'
        print >>output, '\\hline'

        for i, c in enumerate(self.configs):
            line = c + '  & \t\t'

            for d in self.data[i]:
                line += str(d) + '  & \t\t'

            line += ' \\\\'

            print >>output, line
            print >>output, '\\hline'

if __name__ == '__main__':

    template = options.template
    parameters = options.parameter
    values = options.values
    constant = options.constant

    t_file = None
    try:
        t_file = open(template, 'r')
    except:
        print "Can not find template file: %s" % template
        sys.exit(1)

    insert_idx = None
    t_content = t_file.readlines()
    try:
        insert_idx = t_content.index('##CONFIG\n')
    except:
        print '''No '##CONFIG' in template file. Don't know where to
        insert '''
        t_file.close()
        sys.exit(1)
    t_file.close()

    values = values.split(',')
    parameters = parameters.split(',')

    dir_name = (template.split('.'))[0]
    if not os.path.isdir(dir_name):
        os.makedirs(dir_name)

    if constant != '':
        if len(parameters) < 2:
            print '''In constant mode, at least two parameters should be
            given'''
            t_file.close()
            sys.exit(1)

    if options.latex_table_dir:
        ltable = LatexTable()

    for i, v in enumerate(values):
        content = []
        content.extend(t_content)
        if parameters[0] == 'TAGE':
            w_name = (template.split('.'))[0] + '_' + v + 'K' + '.py'
            w_file = open(joinpath(dir_name, w_name), 'w')

            resources = float(v)
            idx = 1
            if options.with_local:

                local_history_length = float(9 + i)
                local_table_size = float(2**local_history_length)
                local_history_table_size = float(64 * (2**i))

                choice_history_length = float(10 + i)
                choice_table_size = float(2**choice_history_length)

                content.insert(insert_idx + (idx), 
                               'cpu.localPredictorSize = %d\n' % \
                               local_table_size)

                idx = idx + 1
                content.insert(insert_idx + (idx), 
                               'cpu.localHistoryBits = %d\n' % \
                               local_history_length)
                
                idx = idx + 1
                content.insert(insert_idx + (idx),
                              'cpu.localHistoryTableSize = %d\n' % \
                              local_history_table_size)

                idx = idx + 1
                content.insert(insert_idx + (idx),
                              'cpu.localCtrBits = %d\n' % \
                              1)

                idx = idx + 1
                content.insert(insert_idx + (idx), 
                               'cpu.choicePredictorSize = %d\n' % \
                               choice_table_size)

                idx = idx + 1
                content.insert(insert_idx + (idx), 
                               'cpu.choiceHistoryBits = %d\n' % \
                               choice_history_length)
                
                idx = idx + 1
                content.insert(insert_idx + (idx),
                              'cpu.choiceCtrBits = %d\n' % \
                              3)

                print "Set choice predictor size to %d\n" % \
                        choice_table_size

                print "Set choice history bits to %d\n" % \
                        choice_history_length

                print "Set local predictor size to %d\n" % \
                        local_table_size

                print "Set local history bits to %d\n" % \
                        local_history_length

                print "Set local history table size to %d\n" % \
                        local_history_table_size 

                if options.latex_table_dir:
                    ltable.add(v + 'KB', 'L hist length',\
                            local_history_length)
                    ltable.add(v + 'KB', 'C hist length',\
                            choice_history_length)

                l_resources = float((((local_table_size * 3) + \
                        (local_history_table_size * \
                        local_history_length)) / 8) / 1024)
                c_resources = float(((choice_table_size * 3) / 8) / \
                        1024)

                print "Local resources: %fKB" % l_resources
                print "Choice resources: %fKB" % c_resources

                resources = resources - l_resources - c_resources
 
            default_table_size = 512 * (2**(i/2))
            num_tagged_tables = int(options.num_tagged_tables)

            tage_param = TAGEParameters(num_tagged_tables,
                                        default_table_size,
                                        resources)

            if options.latex_table_dir:
                ltable.add(v + 'KB', 'Alpha',\
                        tage_param.alpha)
                ltable.add(v + 'KB', 'L1',\
                        tage_param.l1)
                ltable.add(v + 'KB', 'Default table size',\
                        default_table_size)
                ltable.add(v + 'KB', 'Num tagged tables',\
                        num_tagged_tables)

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.btypeTageAlpha = %s\n' % \
                    str(tage_param.alpha))

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.btypeTagel1 = %s\n' % \
                    str(tage_param.l1))

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.btypeTageDefaultTableSize = %s\n' % \
                    str(default_table_size))

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.btypeTageTableSizeMode = %s\n' % \
                    "'HistPower'")

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.btypeTageDefaultCtrBits = %s\n' % \
                    "2")

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.btypeTageTaggedCtrBits = %s\n' % \
                    "3")

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.btypeTageTaggedUsefulCtrBits = %s\n' % \
                    "2")

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.btypeTageTagBits = %s\n' % \
                    "9")

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.btypeTageNumTaggedTables = %d\n' % \
                    num_tagged_tables)

        elif parameters[0] == 'ExitTAGE':
            w_name = (template.split('.'))[0] + '_' + v + 'K' + '.py'
            w_file = open(joinpath(dir_name, w_name), 'w')

            resources = float(v)
            idx = 1
            if options.with_local:

                local_history_length = float(7 + i)
                local_table_size = float(2**local_history_length)
                local_history_table_size = float(64 * (2**i))

                choice_history_length = float(8 + i)
                choice_table_size = float(2**choice_history_length)

                content.insert(insert_idx + (idx), 
                               'cpu.localPredictorSize = %d\n' % \
                               local_table_size)

                idx = idx + 1
                content.insert(insert_idx + (idx), 
                               'cpu.localHistoryBits = %d\n' % \
                               local_history_length)
                
                idx = idx + 1
                content.insert(insert_idx + (idx),
                              'cpu.localHistoryTableSize = %d\n' % \
                              local_history_table_size)

                idx = idx + 1
                content.insert(insert_idx + (idx),
                              'cpu.localCtrBits = %d\n' % \
                              1)

                idx = idx + 1
                content.insert(insert_idx + (idx), 
                               'cpu.choicePredictorSize = %d\n' % \
                               choice_table_size)

                idx = idx + 1
                content.insert(insert_idx + (idx), 
                               'cpu.choiceHistoryBits = %d\n' % \
                               choice_history_length)
                
                idx = idx + 1
                content.insert(insert_idx + (idx),
                              'cpu.choiceCtrBits = %d\n' % \
                              3)

                print "Set choice predictor size to %d\n" % \
                        choice_table_size

                print "Set choice history bits to %d\n" % \
                        choice_history_length

                print "Set local predictor size to %d\n" % \
                        local_table_size

                print "Set local history bits to %d\n" % \
                        local_history_length

                print "Set local history table size to %d\n" % \
                        local_history_table_size 

                if options.latex_table_dir:
                    ltable.add(v + 'KB', 'L hist length',\
                            local_history_length)
                    ltable.add(v + 'KB', 'C hist length',\
                            choice_history_length)

                l_resources = float((((local_table_size * 4) + \
                        (local_history_table_size * \
                        local_history_length)) / 8) / 1024)
                c_resources = float(((choice_table_size * 3) / 8) / \
                        1024)

                print "Local resources: %fKB" % l_resources
                print "Choice resources: %fKB" % c_resources

                resources = resources - l_resources - c_resources
 
            hyst_table_size = float(512 * (2**(i/2)))
            h_resources = float(((hyst_table_size * 4) / 8) / 1024)

            resources = resources - h_resources 

            print "Hyst resources: %fKB" % h_resources

            default_table_size = 512 * (2**(i/2))
            num_tagged_tables = int(options.num_tagged_tables)

            tage_param = TAGEParameters(num_tagged_tables,
                                        default_table_size,
                                        resources)

            if options.latex_table_dir:
                ltable.add(v + 'KB', 'Alpha',\
                        tage_param.alpha)
                ltable.add(v + 'KB', 'L1',\
                        tage_param.l1)
                ltable.add(v + 'KB', 'Default table size',\
                        default_table_size)
                ltable.add(v + 'KB', 'Num tagged tables',\
                        num_tagged_tables)
                ltable.add(v + 'KB', 'H',\
                        hyst_table_size)

            idx = idx + 1
            content.insert(insert_idx + (idx), 
                    'cpu.BTPEntries = %d\n' % \
                    hyst_table_size)

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.hystBTypeIndexMode = %s\n' % \
                    "'AddressAndExit'")

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.bexitTageAlpha = %s\n' % \
                    str(tage_param.alpha))

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.bexitTagel1 = %s\n' % \
                    str(tage_param.l1))

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.bexitTageDefaultTableSize = %s\n' % \
                    str(default_table_size))

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.bexitTageTableSizeMode = %s\n' % \
                    "'HistPower'")

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.bexitTageDefaultCtrBits = %s\n' % \
                    "2")

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.bexitTageTaggedCtrBits = %s\n' % \
                    "3")

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.bexitTageTaggedUsefulCtrBits = %s\n' % \
                    "2")

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.bexitTageTagBits = %s\n' % \
                    "9")

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.bexitTageNumTaggedTables = %d\n' % \
                    num_tagged_tables)

        elif parameters[0] == 'ExitGL':
            w_name = (template.split('.'))[0] + '_' + v + 'K' + '.py'
            w_file = open(joinpath(dir_name, w_name), 'w')

            local_history_length = float(7 + i)
            local_table_size = float(2**local_history_length)
            local_history_table_size = float(64 * (2**i))
            global_history_length = float(10 + i)
            global_table_size = float(2**global_history_length)
            choice_history_length = float(10 + i)
            choice_table_size = float(2**choice_history_length)

            print "Set local history length: %d" % \
                    local_history_length
            print "Set local table size: %d" % \
                    local_table_size
            print "Set local history table size: %d" % \
                    local_history_table_size
            print "Set global history length: %d" % \
                    global_history_length
            print "Set global table size: %d" % \
                    global_table_size
            print "Set choice history length: %d" % \
                    choice_history_length
            print "Set choice table size: %d" % \
                    choice_table_size 

            if options.latex_table_dir:
                ltable.add(v + 'KB', 'L hist length',\
                        local_history_length)
                ltable.add(v + 'KB', 'G hist length',\
                        global_history_length)
                ltable.add(v + 'KB', 'C hist length',\
                        choice_history_length)

            idx = 1
            content.insert(insert_idx + (idx),
                    'cpu.localPredictorSize = %d\n' % \
                    local_table_size)

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.localHistoryTableSize = %d\n' % \
                    local_history_table_size)

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.localHistoryBits = %d\n' % \
                    local_history_length)

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.localCtrBits = %d\n' % \
                    1)

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.globalPredictorSize = %d\n' % \
                    global_table_size)

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.globalHistoryBits = %d\n' % \
                    global_history_length)

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.globalCtrBits = %d\n' % \
                    1)

            idx = idx + 1
            content.insert(insert_idx + (idx), 
                           'cpu.choicePredictorSize = %d\n' % \
                           choice_table_size)

            idx = idx + 1
            content.insert(insert_idx + (idx), 
                           'cpu.choiceHistoryBits = %d\n' % \
                           choice_history_length)
            
            idx = idx + 1
            content.insert(insert_idx + (idx),
                          'cpu.choiceCtrBits = %d\n' % \
                          3)

            g_resources = global_table_size * 4
            l_resources = local_table_size * 4 + \
                    local_history_table_size * local_history_length
            c_resources = choice_table_size * 3

            resources = ((g_resources + l_resources + c_resources) \
                    / 8) / 1024

            print "Overall resources: %fKB\n" % resources
        elif parameters[0] == 'GL':
            w_name = (template.split('.'))[0] + '_' + v + 'K' + '.py'
            w_file = open(joinpath(dir_name, w_name), 'w')

            local_history_length = float(8 + i)
            local_table_size = float(2**local_history_length)
            local_history_table_size = float(64 * (2**i))
            global_history_length = float(10 + i)
            global_table_size = float(2**global_history_length)
            choice_history_length = float(10 + i)
            choice_table_size = float(2**choice_history_length)

            print "Set local history length: %d" % \
                    local_history_length
            print "Set local table size: %d" % \
                    local_table_size
            print "Set local history table size: %d" % \
                    local_history_table_size
            print "Set global history length: %d" % \
                    global_history_length
            print "Set global table size: %d" % \
                    global_table_size
            print "Set choice history length: %d" % \
                    choice_history_length
            print "Set choice table size: %d" % \
                    choice_table_size 

            if options.latex_table_dir:
                ltable.add(v + 'KB', 'L hist length',\
                        local_history_length)
                ltable.add(v + 'KB', 'G hist length',\
                        global_history_length)
                ltable.add(v + 'KB', 'C hist length',\
                        choice_history_length)

            idx = 1
            content.insert(insert_idx + (idx),
                    'cpu.localPredictorSize = %d\n' % \
                    local_table_size)

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.localHistoryTableSize = %d\n' % \
                    local_history_table_size)

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.localHistoryBits = %d\n' % \
                    local_history_length)

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.localCtrBits = %d\n' % \
                    1)

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.globalPredictorSize = %d\n' % \
                    global_table_size)

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.globalHistoryBits = %d\n' % \
                    global_history_length)

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.globalCtrBits = %d\n' % \
                    1)

            idx = idx + 1
            content.insert(insert_idx + (idx), 
                           'cpu.choicePredictorSize = %d\n' % \
                           choice_table_size)

            idx = idx + 1
            content.insert(insert_idx + (idx), 
                           'cpu.choiceHistoryBits = %d\n' % \
                           choice_history_length)
            
            idx = idx + 1
            content.insert(insert_idx + (idx),
                          'cpu.choiceCtrBits = %d\n' % \
                          3)

            g_resources = global_table_size * 3
            l_resources = local_table_size * 3 + \
                    local_history_table_size * local_history_length
            c_resources = choice_table_size * 3

            resources = ((g_resources + l_resources + c_resources) \
                    / 8) / 1024

            print "Overall resources: %fKB\n" % resources

        elif parameters[0] == 'TwostageGL':
            w_name = (template.split('.'))[0] + '_' + v + 'K' + '.py'
            w_file = open(joinpath(dir_name, w_name), 'w')

            local_history_length = float(9 + i)
            local_table_size = float(2**local_history_length)
            local_history_table_size = float(128 * (2**i))
            global_history_length = float(10 + i)
            global_table_size = float(2**global_history_length)
            choice_history_length = float(10 + i)
            choice_table_size = float(2**choice_history_length)

#            hyst_table_size = float(512 * (2**(i/2)))

            print "Set local history length: %d" % \
                    local_history_length
            print "Set local table size: %d" % \
                    local_table_size
            print "Set local history table size: %d" % \
                    local_history_table_size
            print "Set global history length: %d" % \
                    global_history_length
            print "Set global table size: %d" % \
                    global_table_size
            print "Set choice history length: %d" % \
                    choice_history_length
            print "Set choice table size: %d" % \
                    choice_table_size 
#            print "Set hyst size: %d" % \
#                    hyst_table_size

            if options.latex_table_dir:
                ltable.add(v + 'KB', 'L hist length',\
                        local_history_length)
                ltable.add(v + 'KB', 'L table size',\
                        local_table_size)
                ltable.add(v + 'KB', 'L hist table size',\
                        local_history_table_size)
                ltable.add(v + 'KB', 'G hist length',\
                        global_history_length)
                ltable.add(v + 'KB', 'G table size',\
                        global_table_size)
                ltable.add(v + 'KB', 'C hist length',\
                        choice_history_length)
                ltable.add(v + 'KB', 'C table size',\
                        choice_table_size)
#                ltable.add(v + 'KB', 'H table size',\
#                        hyst_table_size)

            # Use a address-only indexed global table as the second
            # stage
            idx = 1
#            content.insert(insert_idx + (idx),
#                    'cpu.globalPredictorSize = %d\n' % \
#                    hyst_table_size)

#            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.binaryLocalPredictorSize = %d\n' % \
                    local_table_size)

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.binaryLocalHistoryTableSize = %d\n' % \
                    local_history_table_size)

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.binaryLocalHistoryBits = %d\n' % \
                    local_history_length)

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.binaryLocalCtrBits = %d\n' % \
                    2)

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.binaryGlobalPredictorSize = %d\n' % \
                    global_table_size)

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.binaryGlobalHistoryBits = %d\n' % \
                    global_history_length)

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.binaryGlobalCtrBits = %d\n' % \
                    2)

            idx = idx + 1
            content.insert(insert_idx + (idx), 
                           'cpu.binaryChoicePredictorSize = %d\n' % \
                           choice_table_size)

            idx = idx + 1
            content.insert(insert_idx + (idx), 
                           'cpu.binaryChoiceHistoryBits = %d\n' % \
                           choice_history_length)
            
            idx = idx + 1
            content.insert(insert_idx + (idx),
                          'cpu.binaryChoiceCtrBits = %d\n' % \
                          3)

            g_resources = global_table_size * 2
            l_resources = local_table_size * 2 + \
                    local_history_table_size * local_history_length
            c_resources = choice_table_size * 3

#            h_resources = hyst_table_size * 3

            resources = ((g_resources + l_resources + c_resources) / 8) / 1024

            print "Overall resources: %fKB\n" % resources

        elif parameters[0] == 'TwostagePiecewise':
            w_name = (template.split('.'))[0] + '_' + v + 'K' + '.py'
            w_file = open(joinpath(dir_name, w_name), 'w')

            table_size = float(8 * (2**(i/3)))
            path_table_size = float(32 * (2**((i+1)/3)))
            history_length = float((4*(2**((i+2)/3))) - 1)

            print "Set table size: %d" % \
                    table_size
            print "Set path table size: %d" % \
                    path_table_size
            print "Set history length: %d" % \
                    history_length

            if options.latex_table_dir:
                ltable.add(v + 'KB', 'Table size',\
                        table_size)
                ltable.add(v + 'KB', 'Path table size',\
                        path_table_size)
                ltable.add(v + 'KB', 'History Length',\
                        history_length)

            idx = 1
            content.insert(insert_idx + (idx),
                    'cpu.pwTableSize = %d\n' % \
                    table_size)

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.pwPathTableSize = %d\n' % \
                    path_table_size)

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.pwHistoryBits = %d\n' % \
                    history_length)

            p_resources = table_size * path_table_size * \
                (history_length + 1) * 8

            h_resources = hyst_table_size * 3

            resources = ((p_resources + h_resources) / 8) / 1024

            print "Overall resources: %fKB\n" % resources

        elif parameters[0] == 'ExitPiecewise':
            w_name = (template.split('.'))[0] + '_' + v + 'K' + '.py'
            w_file = open(joinpath(dir_name, w_name), 'w')

            table_size = float(2 * (2**(i/3)))
            path_table_size = float(16 * (2**((i+1)/3)))
            msb_history_length = float((8*(2**((i+2)/3))) - 1)
            mb_history_length = float((10*(2**((i+2)/3))) - 1)
            lsb_history_length = float((13*(2**((i+2)/3))) - 1)

            print "Set table size: %d" % \
                    table_size
            print "Set path table size: %d" % \
                    path_table_size
            print "Set history length: %d, %d, %d" % \
                    (msb_history_length, mb_history_length,
                     lsb_history_length)

            if options.latex_table_dir:
                ltable.add(v + 'KB', 'Table size',\
                        table_size)
                ltable.add(v + 'KB', 'Path table size',\
                        path_table_size)
                ltable.add(v + 'KB', 'History Length',\
                        history_length)

            idx = 1
            content.insert(insert_idx + (idx),
                    'cpu.pwMsbTableSize = %d\n' % \
                    table_size)

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.pwMbTableSize = %d\n' % \
                    table_size)

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.pwLsbTableSize = %d\n' % \
                    table_size)

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.pwMsbPathTableSize = %d\n' % \
                    path_table_size)

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.pwMbPathTableSize = %d\n' % \
                    path_table_size)

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.pwLsbPathTableSize = %d\n' % \
                    path_table_size)

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.pwMsbHistoryBits = %d\n' % \
                    msb_history_length)

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.pwMbHistoryBits = %d\n' % \
                    mb_history_length)

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.pwLsbHistoryBits = %d\n' % \
                    lsb_history_length)

            msb_resources = table_size * path_table_size * \
                (msb_history_length + 1) * 8

            mb_resources = table_size * path_table_size * \
                (mb_history_length + 1) * 8

            lsb_resources = table_size * path_table_size * \
                (lsb_history_length + 1) * 8

            resources = ((msb_resources + mb_resources + lsb_resources) / 8) / 1024

            print "Overall resources: %fKB\n" % resources

        elif parameters[0] == 'TwostageTAGE':
            w_name = (template.split('.'))[0] + '_' + v + 'K' + '.py'
            w_file = open(joinpath(dir_name, w_name), 'w')

            resources = float(v)
            l_resources = 0
            c_resources = 0
            idx = 1
            if options.with_local:

                local_history_length = float(7 + i)
                local_table_size = float(2**local_history_length)
                local_history_table_size = float(64 * (2**i))

                choice_history_length = float(10 + i)
                choice_table_size = float(2**choice_history_length)

                content.insert(insert_idx + (idx), 
                               'cpu.binaryLocalPredictorSize = %d\n' % \
                               local_table_size)

                idx = idx + 1
                content.insert(insert_idx + (idx), 
                               'cpu.binaryLocalHistoryBits = %d\n' % \
                               local_history_length)
                
                idx = idx + 1
                content.insert(insert_idx + (idx),
                              'cpu.binaryLocalHistoryTableSize = %d\n' % \
                              local_history_table_size)

                idx = idx + 1
                content.insert(insert_idx + (idx),
                              'cpu.binaryLocalCtrBits = %d\n' % \
                              2)

                idx = idx + 1
                content.insert(insert_idx + (idx), 
                               'cpu.binaryChoicePredictorSize = %d\n' % \
                               choice_table_size)

                idx = idx + 1
                content.insert(insert_idx + (idx), 
                               'cpu.binaryChoiceHistoryBits = %d\n' % \
                               choice_history_length)
                
                idx = idx + 1
                content.insert(insert_idx + (idx),
                              'cpu.binaryChoiceCtrBits = %d\n' % \
                              3)

                print "Set choice predictor size to %d\n" % \
                        choice_table_size

                print "Set choice history bits to %d\n" % \
                        choice_history_length

                print "Set local predictor size to %d\n" % \
                        local_table_size

                print "Set local history bits to %d\n" % \
                        local_history_length

                print "Set local history table size to %d\n" % \
                        local_history_table_size 

                if options.latex_table_dir:
                    ltable.add(v + 'KB', 'L hist length',\
                            local_history_length)
                    ltable.add(v + 'KB', 'L table size',\
                            local_table_size)
                    ltable.add(v + 'KB', 'L hist table size',\
                            local_history_table_size)
                    ltable.add(v + 'KB', 'C hist length',\
                            choice_history_length)
                    ltable.add(v + 'KB', 'C table size',\
                            choice_table_size)

                l_resources = float((((local_table_size * 2) + \
                        (local_history_table_size * \
                        local_history_length)) / 8) / 1024)
                c_resources = float(((choice_table_size * 3) / 8) / \
                        1024)

                print "Local resources: %fKB" % l_resources
                print "Choice resources: %fKB" % c_resources

                resources = resources - l_resources - c_resources
 
            hyst_table_size = float(512 * (2**(i/2)))

            # Use a address-only indexed global table as the second
            # stage
            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.globalPredictorSize = %d\n' % \
                    hyst_table_size)

            h_resources = float(((hyst_table_size * 3) / 8) / 1024)

            print "Hyst table resources: %fKB" % h_resources

            resources = resources - h_resources

            default_table_size = 512 * (2**(i/2))
            num_tagged_tables = int(options.num_tagged_tables)

            tage_param = TAGEParameters(num_tagged_tables,
                                        default_table_size,
                                        resources)

            print "Overall fize: %fKB" % (h_resources +\
                    l_resources + c_resources + tage_param.resources)

            if options.latex_table_dir:
                ltable.add(v + 'KB', 'Alpha',\
                        tage_param.alpha)
                ltable.add(v + 'KB', 'L1',\
                        tage_param.l1)
                ltable.add(v + 'KB', 'Default table size',\
                        default_table_size)
                ltable.add(v + 'KB', 'Num tagged tables',\
                        num_tagged_tables)

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.btypeTageAlpha = %s\n' % \
                    str(tage_param.alpha))

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.btypeTagel1 = %s\n' % \
                    str(tage_param.l1))

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.btypeTageDefaultTableSize = %s\n' % \
                    str(default_table_size))

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.btypeTageTableSizeMode = %s\n' % \
                    "'HistPower'")

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.btypeTageDefaultCtrBits = %s\n' % \
                    "2")

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.btypeTageTaggedCtrBits = %s\n' % \
                    "3")

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.btypeTageTaggedUsefulCtrBits = %s\n' % \
                    "2")

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.btypeTageTagBits = %s\n' % \
                    "9")

            idx = idx + 1
            content.insert(insert_idx + (idx),
                    'cpu.btypeTageNumTaggedTables = %d\n' % \
                    num_tagged_tables)

        else:
            w_name = (template.split('.'))[0] + '_' + parameters[0] + '_' + v + '.py'
            w_file = open(joinpath(dir_name, w_name), 'w')
            content.insert(insert_idx + 1, 'cpu.%s = %s\n' % (parameters[0], v))

        if constant != '':
            v2 = int(constant) / int(v)
            content.insert(insert_idx + 2, 'cpu.%s = %d\n' %\
                    (parameters[1], v2))

        if options.latex_table_dir:
            ltable.output(options.latex_table_dir)

        print 'Generating %s ...' % w_name 
        print
        for c in content:
            w_file.write(c)

        w_file.close()

sys.exit(0)

